package com.afeng.web.rest.interceptor;

import com.afeng.util.log.LogMessageUtil;
import com.afeng.util.log.TraceSpanIdGeneratorUtil;
import com.alibaba.fastjson.JSON;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 * 
 * @Title       : LoggerInterceptor
 * @Description : 日志拦截器
 * @Date        : 2017年11月16日
 * @author      : afeng
 */
@Component
public class LoggerInterceptor extends HandlerInterceptorAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoggerInterceptor.class);
    //日志拦截器专用，记录请求总耗时
    private ThreadLocal<Long> time = new ThreadLocal<Long>();
    private static final String COM_REQUEST_IN = "com_request_in";
    private static final String COM_REQUEST_OUT = "com_request_out";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        time.set(System.currentTimeMillis());

        /*
         * 从header后去traceid和spanid，如果为空，则生成一个新的
         */
        String traceId = request.getHeader(LogMessageUtil.TRACE_ID_FLAG);
        String spanId = request.getHeader(LogMessageUtil.SPAN_ID_FLAG);
        if (StringUtils.isBlank(traceId)) {
            traceId = TraceSpanIdGeneratorUtil.generateTraceIdOrSpanId();
        }
        if (StringUtils.isBlank(spanId)) {
            spanId = TraceSpanIdGeneratorUtil.generateTraceIdOrSpanId();
        }
        /*
         * 获取token，并通过token和约定规则，解密出user
         */
        String token = request.getHeader("token");
        String user = "";
        if (StringUtils.isBlank(token)) {
            user = "anonymous";
        } else {
            //user = base64Util.decrypt(token);
            user = "";
        }
        /*
         * 获取不到nginx设置的ip 取代理服务器的ip
         */
        String realIp = request.getHeader("X-Forward-For");
        String proxyIp = request.getRemoteAddr();
        String ip = "";
        if (StringUtils.isBlank(realIp)) {
            ip = proxyIp;
        } else {
            ip = realIp;
        }
        /*
         * 请求uri和args请求参数
         */
        String uri = request.getRequestURI();
        Map<String, Object> params = new HashMap<>(request.getParameterMap());
        String args = params.size() > 0 ? JSON.toJSONString(params) : StringUtils.EMPTY;
        
        /*
         * 记录请求入口服务日志
         */
        LogMessageUtil logMessageUtil = new LogMessageUtil();
        LogMessageUtil.setTraceId(traceId);
        LogMessageUtil.setSpanId(spanId);
        logMessageUtil.setDltag(COM_REQUEST_IN);
        logMessageUtil.add("uri", uri);
        logMessageUtil.add("args", args);
        logMessageUtil.add("user", user);
        logMessageUtil.add("ip", ip);
        logMessageUtil.add("token", token);
        LOGGER.info(logMessageUtil.toString());
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {

        Long proc_time = System.currentTimeMillis() - time.get();
        time.remove();

        String uri = request.getRequestURI();
        
        LogMessageUtil logMessageUtil = new LogMessageUtil();
        logMessageUtil.setDltag(COM_REQUEST_OUT);
        logMessageUtil.add("uri", uri);
        logMessageUtil.add("proc_time", proc_time);
        LOGGER.info(logMessageUtil.toString());
    }
}
